import React, { useRef, useState, useEffect } from 'react';
import { Button, Drawer, message } from 'antd';
import 'animate.css';
import {
  NumberOutlined
} from '@ant-design/icons';
import EasyTyper from 'easy-typer-js'
import style from './index.less';

const animateEnterList = [
  'fadeIn', 'fadeInDown', 'fadeInLeft', 'fadeInRight', 'fadeInUp',
  'fadeInTopLeft', 'fadeInTopRight', 'fadeInBottomLeft', 'fadeInBottomRight',
  'rotateInDownLeft', 'rotateInDownRight', 'rotateInUpLeft', 'rotateInUpRight', 'slideInDown',
  'slideInLeft', 'slideInRight', 'slideInUp', 'zoomInDown', 'zoomInLeft', 'zoomInRight', 'zoomInUp'
];
const animateLeaveList = [
  'fadeOut', 'fadeOutDown', 'fadeOutLeft', 'fadeOutRight', 'fadeOutUp',
  'fadeOutTopLeft', 'fadeOutTopRight', 'fadeOutBottomLeft', 'fadeOutBottomRight',
  'rotateOutDownLeft', 'rotateOutDownRight', 'rotateOutUpLeft', 'rotateOutUpRight', 'slideOutDown',
  'slideOutLeft', 'slideOutRight', 'slideOutUp', 'zoomOutDown', 'zoomOutLeft', 'zoomOutRight', 'zoomOutUp'
];

let audioQueue = [];
let imageQueue = [];
let videoQueue = [];
let currentIndex = 0
let currentImageIndex = 0; // 当前展示的图片索引
let playNextSTO = null;

const HomePage = () => {
  const [isPlayingAudio, setIsPlayingAudio] = useState(false);
  const [isPlayingVideo, setIsPlayingVideo] = useState(false);
  const [isDisplayingImages, setIsDisplayingImages] = useState(false);
  const [isPaused, setIsPaused] = useState(false);
  const [imageUrl, setImageUrl] = useState('');
  const [showSubtitles, setShowSubtitles] = useState('');
  const [show, setShow] = useState('none'); // none, image, video
  const [titleArr, setTitleArr] = useState([])
  const [titleVisible, setTitleVisible] = useState(false)
  const [titleKey, setTitleKey] = useState()
  const [open, setOpen] = useState(false)

  const audioElement = useRef(null);
  const videoElement = useRef(null);
  const imageTimeouts = useRef([]);
  const imageRef = useRef(null);
  const typer = useRef(null);
  const mainRef = useRef(null);


  useEffect(() => {
    // socket.io
    const script = document.createElement('script');
    script.src = 'https://cdn.socket.io/4.0.0/socket.io.min.js'
    script.async = true;
    script.onload = () => {
      const socket = io();

      socket.on('audio', (audioDataArray) => {
        console.log('audio', audioDataArray, isPlayingAudio)
        audioQueue = [...audioQueue, ...audioDataArray];
        if (!isPlayingAudio) playNext();
      });

      socket.on('image', (imageSrcArray) => {
        console.log('image', imageSrcArray)
        imageQueue = [...imageQueue, ...imageSrcArray];
        // if (currentIndex < audioQueue.length) {
        startImage(imageQueue);
        // }
      });

      socket.on('video', (videoSrcArray) => {
        console.log('video', videoSrcArray)
        videoQueue = [...videoQueue, ...videoSrcArray];
        // if (currentIndex < audioQueue.length)
        playVideo(videoSrcArray[0]);
      });

      socket.on('title', (titleObj) => {
        console.log('title', titleObj)
        if (titleObj?.key) {
          setTitleKey(titleObj?.key)
        }
        setTitleArr(titleObj?.titles)
      });

      socket.on('clear', () => {
        clearAllTimeouts();
        audioQueue = [];
        imageQueue = [];
        videoQueue = []
        currentIndex = 0
        currentImageIndex = 0
        setShowSubtitles('');
        setShow('none');
        setImageUrl('');
      });

      socket.on('paused', () => {
        setIsPaused(true);
        clearAllTimeouts();
        if (isPlayingAudio && audioElement.current) audioElement.current.pause();
        if (isPlayingVideo && videoElement.current) videoElement.current.pause();
      });

      socket.on('resume', () => {
        setIsPaused(false);
        playNext();
        if (audioElement.current) audioElement.current.play().catch(console.error);
        if (videoElement.current) videoElement.current.play().catch(console.error);
      });


    }
    document.body.appendChild(script);

    // // live2d
    // const scripts = document.createElement('script');
    // scripts.src = 'https://unpkg.com/oh-my-live2d@latest'
    // scripts.async = true;
    // scripts.onload = () => {
    //   OML2D.loadOml2d({
    //     models: [
    //       {
    //         path: 'https://model.oml2d.com/HK416-1-normal/model.json',
    //         position: [0, 0],
    //         scale: 0.03,
    //         stageStyle: {

    //         },
    //         volume: 0,
    //       }
    //     ],
    //     tips: {
    //       copyTips: {
    //         message: []
    //       },
    //       idleTips: {
    //         message: []
    //       }
    //     },
    //     menus: {
    //       disable: true
    //     },
    //     statusBar: {
    //       disable: true
    //     },
    //     parentElement: document.getElementById('bottom')
    //   });
    // }
    // document.body.appendChild(scripts);


    return () => {
      document.body.removeChild(script);
      // document.body.removeChild(scripts);
      typer.current?.close()
    }
  }, [])

  useEffect(() => {
    console.log('title唤醒', titleArr.length, titleVisible, titleKey, audioQueue, audioQueue[audioQueue.length - 1]?.key === titleKey)
    if (titleArr.length > 0 && titleVisible) {
      if (titleKey) {
        if (audioQueue[audioQueue.length - 1]?.key === titleKey) {
          setOpen(true)
        }
      } else {
        setOpen(true)
      }
    } else {
      setOpen(false)
    }
  }, [titleArr.length, titleVisible, titleKey, JSON.stringify(audioQueue)])


  const animateCSS = async (animation, prefix = 'animate__') =>
    new Promise((resolve) => {
      if (imageRef.current) {
        const animationClass = `${prefix}animated ${prefix}${animation}`;
        imageRef.current.classList.add(...animationClass.split(' '));

        const handleAnimationEnd = (event) => {
          event.stopPropagation();
          imageRef.current.classList.remove(...animationClass.split(' '));
          resolve('Animation ended');
        };

        imageRef.current.addEventListener('animationend', handleAnimationEnd, { once: true });
      }
    });

  const startImage = async (imageSrcArray) => {
    setShow('image');
    const duration = 2000; // 进入和离开动画的时间均为1秒
    const totalDuration = 6000; // 每个图片动画周期的总时间

    async function showNextImage() {
      if (currentImageIndex >= imageSrcArray.length) return;
      const image = imageSrcArray[currentImageIndex];
      setImageUrl(image);
      const animateEnter = animateEnterList[Math.floor(Math.random() * animateEnterList.length)];
      await animateCSS(animateEnter);
      const remainingTime = totalDuration - 2 * duration;
      await new Promise(resolve => setTimeout(resolve, remainingTime));

      if (currentImageIndex < imageSrcArray.length - 1) {
        const animateLeave = animateLeaveList[Math.floor(Math.random() * animateLeaveList.length)];
        await animateCSS(animateLeave);
        setImageUrl('');
      }
      currentImageIndex++;
      await showNextImage();

    }
    await showNextImage();
  };

  const clearAllTimeouts = () => {
    imageTimeouts.current.forEach((timeout) => clearTimeout(timeout));
    imageTimeouts.current = [];
  }

  const checkAllQueuesCompleted = () => {
    // 判断音频、图片和视频队列是否都播放完毕
    console.log('currentIndex', currentIndex, audioQueue.length, videoQueue.length, currentImageIndex, imageQueue.length, 'if', isPlayingAudio, isDisplayingImages, isPlayingVideo)
    return currentIndex >= audioQueue.length &&
      !isPlayingAudio &&
      !isDisplayingImages &&
      currentIndex >= videoQueue.length &&
      currentImageIndex >= imageQueue.length &&
      !isPlayingVideo;
  }

  const playNext = () => {
    console.log('next', currentIndex, audioQueue.length, videoQueue.length, currentImageIndex, imageQueue.length)
    if (isPaused) return;
    if (checkAllQueuesCompleted()) {
      if (currentIndex < audioQueue.length) {
        currentIndex += 1
      }
      clearAllTimeouts();
      clearTimeout(playNextSTO)
      setTitleVisible(true);
      return;
    }
    setTitleVisible(false)
    if (currentIndex < audioQueue.length && !isPlayingAudio) {
      const audioData = audioQueue[currentIndex];
      displayText(audioData.content);
      playAudio(audioData.audio);
      return;
    }

    // if (imageQueue.length > 0 && !isDisplayingImages && !isPlayingVideo) {
    //   displayImages(imageQueue);
    //   return;
    // }

    // 只有当没有图片展示时才播放视频
    // if (currentIndex < videoQueue.length && !isPlayingVideo && !isDisplayingImages) {
    //   playVideo(videoQueue[currentIndex]);
    //   return;
    // }

    if (currentImageIndex < imageQueue.length && !isDisplayingImages) {
      //!isPlayingVideo
      playNextSTO = setTimeout(playNext, 5000);
    }
  };

  const displayText = (textData) => {
    initTyper(textData)
  };

  const playAudio = (audioSrc) => {
    setIsPlayingAudio(true);
    audioElement.current.src = audioSrc;

    audioElement.current.play().catch(() => {
      if (currentIndex < audioQueue.length) {
        currentIndex += 1
      }
      playNext();
    });

    audioElement.current.onended = () => {
      setIsPlayingAudio(false);
      if (currentIndex < audioQueue.length) {
        currentIndex += 1
      }
      playNext();
    };
  };

  const displayImages = (imageSrcArray) => {
    if (imageSrcArray.length === 0) return;

    setIsDisplayingImages(true);

    // 直接调用 startImage 进行展示动画
    startImage(imageSrcArray).then(() => {
      setIsDisplayingImages(false);
      if (currentIndex < audioQueue.length) {
        currentIndex += 1
      }
      playNext();
    });
  };

  const playVideo = (videoSrc) => {
    setShow('video');
    setIsPlayingVideo(true);
    videoElement.current.src = videoSrc

    videoElement.current.play().catch(() => {
      if (currentIndex < audioQueue.length) {
        currentIndex += 1
      }
      playNext();
    });

    videoElement.current.onended = () => {
      setIsPlayingVideo(false);
      if (currentIndex < audioQueue.length) {
        currentIndex += 1
      }
      playNext();
    };
  };

  const mock = () => {
    const query = '给我讲一下三大纪律和六项注意'
    fetch('/commentary', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "query": query,
        "generate_abstract": true
      })
    })
      .then(response => response?.json())
  }

  const mock2 = () => {
    if (!titleArr?.length) {
      message.info('正在生成摘要，请稍后')
      return
    }
    fetch('/commentary', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "query": titleArr?.[0],
        "generate_abstract": false
      })
    })
      .then(response => response?.json())
  }

  const onClose = () => {
    setTitleVisible(false)
    setTitleKey('')
    setTitleArr([])
  }

  const clear = () => {
    fetch('/clear', {
      method: 'POST',
    })
      .then(response => response?.json())
  }

  // 打字机
  const initTyper = (text) => {
    // 配置对象
    const obj = {
      output: '',
      isEnd: false,
      speed: 200,
      singleBack: false,
      sleep: 0,
      type: 'normal',
      backSpeed: 40,
      sentencePause: false
    }
    // 实例化
    typer.current = new EasyTyper(obj, text, completeAsentence, changeOutput)
  }

  // 输出完毕后的回调函数
  const completeAsentence = () => {
    console.log('输出完毕！长官！')
  }

  // 钩子函数和setState结合
  const changeOutput = (output) => {
    // output为流式的累加的字符串，例如：'我是一只鸟'， 打印出来就是：'我'、'我是'、'我是一'、'我是一只'、'我是一只鸟'
    const maxLength = 50
    const endsymbol = [',', '，', '.', '。', '!', '！', '?', '？']
    let str = ''

    for (let i = 0; i < output.length; i += maxLength) {
      str = output.substring(i, i + maxLength)
      if (endsymbol.includes(str.charAt(str.length - 1))) {
        str = str.substring(0, str.length)
        setShowSubtitles(str)
      } else {
        setShowSubtitles(str)
      }
    }
  }

  return (
    <div className={style.main} ref={e => mainRef.current = e}>
      <div className={style.top}>
        <Button onClick={mock}>mock1</Button>
        <Button onClick={mock2}>mock2</Button>
        <Button onClick={clear}>clear</Button>
      </div>
      <div className={style.content}>
        <img ref={imageRef} src={imageUrl} className={`images`} style={{ display: show === 'image' ? 'block' : 'none' }} />
        <video ref={videoElement} controls={false} style={{ display: show === 'video' ? 'block' : 'none' }} />
        <audio ref={audioElement} />
      </div>
      <div id="bottom" className={style.bottom}>
        <div className={style.textComponent}>{showSubtitles}</div>
      </div>
      <Drawer
        getContainer={mainRef.current}
        placement="bottom"
        closable={false}
        onClose={onClose}
        open={open}
      >
        <div className={style.drawer_body}>
          {
            titleArr?.map((e, index) => (
              <div className={style.drawer_item} key={index}>
                <NumberOutlined style={{ color: '#4A3728', marginRight: 20 }} />
                <span>{e}</span>
              </div>
            ))
          }
        </div>
      </Drawer>
    </div>
  );
};


export default HomePage;
